#ifndef _math_traits_spec_hpp_
#define _math_traits_spec_hpp_

namespace core {

    namespace math {

        //specialization for standard types
        #define MATH_IS_VECTOR(T)                   \
        template<>                                  \
            struct is_vector<T> :   public true_    \
            { };

        #define MATH_IS_NOT_VECTOR(T)               \
        template<>                                  \
            struct is_vector<T> :   public false_   \
        { };

        #define MATH_IS_SCALAR(T)                   \
        template<>                                  \
            struct is_scalar<T> :   public true_    \
            { };

        #define MATH_INTEGRAL_SPECIALIZATION(T)     \
            MATH_IS_SCALAR(T)                       \
            MATH_IS_NOT_VECTOR(T)

        //specializations for builtin types
        MATH_INTEGRAL_SPECIALIZATION(char)
        MATH_INTEGRAL_SPECIALIZATION(unsigned char)
        MATH_INTEGRAL_SPECIALIZATION(short)
        MATH_INTEGRAL_SPECIALIZATION(unsigned short)
        MATH_INTEGRAL_SPECIALIZATION(int)
        MATH_INTEGRAL_SPECIALIZATION(unsigned int)
        MATH_INTEGRAL_SPECIALIZATION(float)
        MATH_INTEGRAL_SPECIALIZATION(double)
        MATH_INTEGRAL_SPECIALIZATION(bool)


        #undef MATH_INTEGRAL_SPECIALIZATION
        #undef MATH_IS_VECTOR
        #undef MATH_IS_NOT_VECTOR
        #undef MATH_IS_SCALAR

        //specialization for known classes
        template<class T, std::size_t N>
            struct is_vector<boost::array<T,N> >
            :   public if_< is_scalar<T>,
                true_,
                false_
                >::type
            { };
        template<class T, std::size_t N>
            struct is_vector<T[N] >
            :   public if_< is_scalar<T>,
                true_,
                false_
                >::type
            { };
        template<class T, class A>
            struct is_vector<std::vector<T,A> >
            :   public if_< is_scalar<T>,
                true_,
                false_
                >::type
            { };
        template<class T>
            struct is_vector<std::valarray<T> >
            :   public if_< is_scalar<T>,
                true_,
                false_
                >::type
            { };

    } // namespace math

} // namespace core
#endif // _math_traits_spec_hpp_
